﻿using System;
using System.Collections.Generic;
using System.Linq;
using EYCmsAdmin.Domain.Models;
using EYCmsAdmin.Domain.RepositoryInterfaces;
using EYCmsAdmin.NHibernate.NHibernateManager;
using NHibernate;
using NHibernate.Linq;

namespace EYCmsAdmin.NHibernate.Repository
{
    public class BaseRepository<T> : IBaseRepository<T> where T : class, IBaseDomainModel
    {
        private readonly string sessionName;

        public BaseRepository(string sessionName)
        {
            if (string.IsNullOrEmpty(sessionName))
            {
                throw new ArgumentException("connectionString may not be null nor empty");
            }

            this.sessionName = sessionName;
        }

        protected ISession NHibernateSession
        {
            get
            {
                return NHibernateSessionManager.Instance.GetSessionFrom(this.sessionName);
            }
        }

        public T Add(T model)
        {
            using (ITransaction transaction = NHibernateSession.BeginTransaction())
            {
                this.NHibernateSession.Save(model);
                this.NHibernateSession.Flush();
                transaction.Commit();
                return model;
            }
        }

        public T Edit(T model)
        {
            using (ITransaction transaction = NHibernateSession.BeginTransaction())
            {
                this.NHibernateSession.SaveOrUpdate(model);
                this.NHibernateSession.Flush();
                transaction.Commit();
                return model;
            }
        }

        public IList<T> GetAll()
        {
            return Query().ToList();
        }

        public T Get(int id)
        {
            return NHibernateSession.Get<T>(id);
        }

        public void Delete(int id)
        {
            using (ITransaction transaction = NHibernateSession.BeginTransaction())
            {
                this.NHibernateSession.Delete(id);
                this.NHibernateSession.Flush();
                transaction.Commit();
            }
        }

        public void Delete(T model)
        {
            using (ITransaction transaction = NHibernateSession.BeginTransaction())
            {
                this.NHibernateSession.Delete(model);
                this.NHibernateSession.Flush();
                transaction.Commit();
            }
        }

        public IQueryable<T> Query()
        {
            return this.NHibernateSession.Query<T>();
        }

        public IQueryable<U> Query<U>() where U : IBaseDomainModel
        {
            return NHibernateSession.Query<U>();
        }
    }
}